package cn.com.zcode.email.model;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import cn.com.zcode.user.model.InviteCode;
import cn.com.zcode.user.model.User;

public class EmailFactory {
	private Logger logger = Logger.getLogger(EmailFactory.class);
	private static final Pattern PATTERN_PROPERTY = Pattern.compile("(\\s*\\w*\\s*=\\s*\\w*\\s*)");
	private static final Pattern PATTERN_EXPRE = Pattern.compile("\\$\\{[^\\}]*\\}", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);

	private static final String REGEX_REPART_START = "\\$\\{r\\:s(\\s*\\w*\\s*=\\s*\\w*\\s*)*\\}";
	private static final String REGEX_REPART_END = "\\$\\{r\\:e\\s*\\}";

	public EmailFactory() {
		super();
	}

	public String complite(String data, Map<String, Object> obj, String head) {
		int i = 0;
		int pos = 0;
		StringBuffer sb = new StringBuffer();
		Matcher m = PATTERN_EXPRE.matcher(data);
		String key = null;
		while (m.find()) {
			String txt = m.group();
			int start = m.start();
			int end = m.end();
			if (txt.matches(REGEX_REPART_START)) {
				if (key == null) {
					String str = data.substring(pos, start);
					sb.append(str);
					pos = end;
					key = txt;
					// System.out.println("1." + txt);
				}
				++i;
			} else if (txt.matches(REGEX_REPART_END)) {
				--i;
				if (i == 0) {
					String str = data.substring(pos, start);
					// System.out.println("2." + key);
					Map<String, String> proMap = getProperty(key);
					String var = proMap.get("var");
					String items = proMap.get("items");

					Object list = obj.get(items);
					if (list != null && list instanceof Iterable) {
						Iterable<?> its = (Iterable<?>) list;
						for (Object object : its) {
							obj.put(var, object);
							sb.append(this.complite(str, obj, var));
						}
					}
					pos = end;
					key = null;
				}
			} else {
				if (i == 0) {
					String str = data.substring(pos, start);
					sb.append(str);
					sb.append(this.fillData(txt, obj, head));
					pos = end;
					// System.out.println("4." + str);
					// System.out.println("5." + txt);
				}
			}

		}
		// System.out.println("3." + data.substring(pos));
		sb.append(data.substring(pos));
		return sb.toString();

	}

	private String fillData(String temp, Map<String, Object> data, String head) {
		Pattern pattern = Pattern.compile("\\$\\{\\s*(.+)\\s*\\}");
		Matcher matcher = pattern.matcher(temp);
		while (matcher.find()) {
			String string = matcher.group();
			String key = string.substring(string.indexOf("${") + 2, string.lastIndexOf("}"));
			if (head != null && key.matches("^\\s*" + head.trim())) {
				key = key.substring(key.indexOf("."));
			}
			Object value = null;
			try {
				value = BeanUtils.getProperty(data, key);
			} catch (Exception e1) {
				logger.warn("can not found the property value for "+key);
			}
			int s = matcher.start();
			int e = matcher.end();
			temp = temp.substring(0, s) + value + temp.substring(e);
		}

		return temp;
	}

	private Map<String, String> getProperty(String key) {
		Map<String, String> map = new HashMap<String, String>();
		Matcher matcher = PATTERN_PROPERTY.matcher(key);
		while (matcher.find()) {
			String text = matcher.group();
			String[] arr = text.split("=");
			map.put(arr[0].trim(), arr[1].trim());

		}
		return map;
	}

	public String getTitle(XmlEmailTemp xmlEmailTemp, Map<String, Object> obj) {
		return this.complite(xmlEmailTemp.getTitle(), obj, null);
	}

	public String getBody(XmlEmailTemp xmlEmailTemp, Map<String, Object> obj) {
		return this.complite(xmlEmailTemp.getBody(), obj, null);
	}

	 
}
